package cn.edu.scau.daoImpl;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import cn.edu.scau.dao.BaseDao;

@Repository("baseDaoImpl")
public class BaseDaoImpl<T> implements BaseDao<T> {
	
	@Resource(name="sessionFactory")
	private SessionFactory sessionFactory;
	
	public T find(Class<T> entityClazz, Serializable id) {
		Session session = getSessionFactory().openSession();
		T t = session.get(entityClazz,id);
		session.flush();
		session.close();
		return t;
	}
	
	public void save(T entity) {
		Session session = getSessionFactory().openSession();
		session.save(entity);
		session.flush();
		session.close();
	}
	
	public void update(T entity) {
		Session session = getSessionFactory().openSession();
		session.saveOrUpdate(entity);
		session.flush();
		session.close();
	}

	public void delete(T entity) {
		Session session = getSessionFactory().openSession();
		session.delete(entity);
		session.flush();
		session.close();
	} 

	public void delete(Class<T> entityClazz, Serializable id) {
		
		Session session = getSessionFactory().openSession();
		session.createQuery(
				"delete "+entityClazz.getSimpleName()+" en where en.id = ?0")
		.setParameter("0",id)
		.executeUpdate();
		session.flush();
		session.close();
	}

	public List<T> findAll(Class<T> entityClazz) {
		return findByHql("select en from "+entityClazz.getSimpleName()+" en");
	}

	public long findCount(Class<T> entityClazz) {
		List<?> list = findByHql("select count(*) from "+entityClazz.getSimpleName());
		if(list!=null&&list.size()==1){
			return (Long) list.get(0);
		}
		return  0; 
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findByHql(String hql){
		Session session = getSessionFactory().openSession();
		List<T> list = session.createQuery(hql).list();
		session.flush();
		session.close();
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findByHql(String hql,Object...objects){
		Session session = getSessionFactory().openSession();
		Query query = session.createQuery(hql);
		for(int i=0;i<objects.length;i++){
			query.setParameter(i+"", objects[i]);
		}
		List<T> list = query.list();
		session.flush();
		session.close();
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findByPage(String hql,int pageNo,int pageSize){
		
		Session session = getSessionFactory().openSession();
		List<T> list = session
				.createQuery(hql)
				.setFirstResult((pageNo-1)*pageSize)
				.setMaxResults(pageSize)
				.list();
		session.flush();
		session.close();
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findByPage(String hql,int pageNo,int pageSize,Object...objects){
		Session session = getSessionFactory().openSession();
		Query query =  session
				.createQuery(hql);
		for(int i=0;i<objects.length;i++){
			query.setParameter(i+"",objects[i]);
		}
		List<T> list = query.setFirstResult((pageNo-1)*pageSize)
				.setMaxResults(pageSize)
				.list();
		session.flush();
		session.close();
		return list;
	}
		
	
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
}
